import java.util.ArrayList;
import java.util.Scanner;

/**
 * Created by L.jp
 * Description:链接：https://www.nowcoder.com/questionTerminal/11cc498832db489786f8a03c3b67d02c
 * 来源：牛客网
 *
 * 输入两个整数 n 和 m，从数列1，2，3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来
 *
 * 输入描述:
 * 每个测试输入包含2个整数,n和m
 *
 *
 * 输出描述:
 * 按每个组合的字典序排列输出,每行输出一种组合
 * 示例1
 * 输入
 * 5 5
 * 输出
 * 1 4<br/>2 3<br/>5
 * User: 86189
 * Date: 2022-04-19
 * Time: 18:53
 */
public class Main {
    //总的结果集
    static   ArrayList<ArrayList<Integer>> ret=new ArrayList<>();
    //每一个符合目标和的结果集，子集
    static ArrayList<Integer> tmp=new ArrayList<>();
    public static void main(String[] args) {
        /*  dfs+回溯
                    我们从第一个元素开始，遍历到一个元素就加入临时集合的顺序表，然后再累加下一个，就是让下标+1，然后累加上当前元素，直到累加和
                    大于或等于目标和，如果等于目标和就把临时集合加入最终的结果集，然后就是回溯，也就是从上一次累加的位置开始判断，回溯的方法就是
                    删除当前临时结果的最后一个元素，然后回到循环中找下一个坐标元素，把它加入临时结果集，累计他，然后判断是否等于目标和
                    如果大于目标和也是要直接返回去找下一个组合
        *
        * */
        Scanner scan=new Scanner(System.in);
        while(scan.hasNext()){
            //从1~n的数
            int n=scan.nextInt();
            //目标和是m
            int m=scan.nextInt();
            dfs(1,0,n,m);
            //按格式输出，要输出每一组结果，每一个元素之间有空格
            for(ArrayList<Integer> list:ret){
                for(int i = 0; i <list.size()-1; i++){
                    System.out.print(list.get(i)+" ");
                }
                //最后一个元素之后要换行，以便输出下一组结果
                System.out.println(list.get(list.size() - 1));
            }
        }
    }
    //这里我们使用从目标和逐渐递减的方法，也可以从每一个元素逐渐递增的方法
    public static  void  dfs(int index,int sum,int end,int target){
        //如果累加和大于等于目标和
        if(sum>=target){
            //如果等于说明这个临时的结果是符合的，可以加入最终结果集,也要返回去找下一组集合
            if(sum==target) {
                ret.add(new ArrayList<Integer>(tmp));
            }
            //如果大于目标和，说明本轮搜索中index以后的数都不可能等于目标和了，直接返回去删除最后一个元素
            //也要往回退，去搜索其他的组合
            return;
        }else{
            //从给定坐标开始去查找组合
            for(int i = index; i <=end; i++){
                //如果元素本身大于目标和，那么直接退出循环
                if(i>target){
                    break;
                }
                //先把元素加入
                tmp.add(i);
                //然后递归累加下一个，累加和也要更新
                //下一次累加的时候，应该从当前位置开始，而不是一直是从1开始
                dfs(i+1,sum+i,end,target);
                //回溯
                //返回到这里说明累计和大于目标和
                tmp.remove(tmp.size()-1);
            }
        }
    }
}
